# @author: caijiaming
# @Time 2023/8/30 15:4z

import re   #引入正则表达式内置库
import os   #引入操作系统内置库

def menu():
    #系统选择菜单
    print('''
    ｜————————————————————————————学生信息管理系统————————————————————————————————｜
    ｜                                                                         ｜
    ｜   ===========================功能菜单===============================     ｜
    ｜                                                                         ｜
    ｜   1 录入学生信息                                                          ｜
    ｜   2 查找学生信息                                                          ｜
    ｜   3 删除学生信息                                                          ｜
    ｜   4 修改学生信息                                                          ｜
    ｜   5 排序                                                                 ｜
    ｜   6 统计学生总人数                                                         ｜
    ｜   7 显示所有学生信息                                                       ｜
    ｜   0 退出系统                                                              ｜
    ｜  =====================================================================  ｜
    ｜   说明：通过数字或⬆⬇方向键选择菜单                                           ｜
    ｜——————————————————————————————————————————————————————————————————————————｜
    ''')

#录入学生信息
def insert():
    #定义一个空列表
    students = []
    mask = True
    while(mask):
        id = input("请输入ID（如：1001）：")
        #ID为空跳出循环
        if not id:
            break
        name = input("请输入学生姓名：")
        #学生姓名为空，跳出循环
        if not name:
            break
        try:
            english = input("请输入英语成绩：")
            python = input("请输入python成绩：")
            c = input("请输入c语言成绩：")
        except:
            print("输入无效，不是整型数值，请重新输入")
            continue
       #将学生信息保存到字典
        student = {"id":id,"name":name,"english":english,"python":python,"c":c}
        #将字典保存到列表中
        students.append(student)
        #提示是否继续添加
        inputMask = input("是否继续添加（y/n）:")
        if inputMask == 'y':
            mask = True
        else:
            mask = False

    #保存数据到文件
    save(students)
    print("学生信息录入完毕！！！")
    show()

#查找学生信息
def search():
    mark = True
    student_query = []
    while mark:
        if os.path.exists("students.txt"):
            id = ""
            name = ""
            mode = input("按ID查输入1，按姓名查输入2：")
            if mode == '1':
                id = input("请输入学生ID：")
            elif mode == '2':
                name = input("请输入学生姓名：")
            else:
                print("你的输入有误，请重新输入")
                search()
            #读取文件保存的数据信息
            with open("students.txt",'r') as rfile:
                student_old = rfile.readlines()
                for student in  student_old:
                    d = dict(eval(student))
                    if id != '':
                        if id == d['id']:
                            #按ID查找，将查找到的学生信息追加到列表中
                            student_query.append(d)
                    elif name != '':
                        if name == d['name']:
                            # 按姓名查找，将查找到的学生信息追加到列表中
                            student_query.append(d)
                #显示查询到学生信息
                show_students(student_query)
                #显示完信息，清空列表
                student_query.clear()
                #是否继续查找
                inputMark = input("是否继续查询（y/n）:")
                if inputMark == 'y':
                    mark = True
                else:
                    mark = False
        else:
            print("系统为保存任何学生信息")
            return

#删除学生信息
def delete():
    mark = True
    while(mark):
        studentId = input("请输入要删除的学生ID：")
        if studentId != "":
            #判断文件是否存在
            if os.path.exists("students.txt"):
                #文件存在，打开文件,只读模式打开
                with open("students.txt",'r') as rfile:
                    #读取文件所有内容
                    student_old = rfile.readlines()
            else:
                #文件不存在即没有内容
                student_old = []
            #是否删除标记
            isDel = False
            #存在学生信息
            if student_old:
                #以写的方式打开文件
                with open("students.txt","w") as wfile:
                    d = {}
                    #循环遍历老数据信息
                    for list in student_old:
                        #将读取字符串信息转换成字典
                        d = dict(eval(list))
                        if d['id'] != studentId:
                            #和输入的学生id做对比，不一致的转成字符串后重新写入文件中
                            wfile.write(str(d)+"\n")
                        else:
                            # 对比学生ID是否一致，一致标记为删除
                            isDel = True
                if isDel:
                    print("ID为 %s 的学生信息已经被删除..." %studentId)
                else:
                    print("没有找到ID为 %s 的学生..." %studentId)
            else:
                print("无学生信息！！")
                break
        show()
        inputMask = input("是否继续删除（y/n）:")
        if inputMask == 'y':
            mark = True
        else:
            mark = False

#修改学生信息
def modify():
    show()
    if os.path.exists("students.txt"):
        with open("students.txt", 'r') as rfile:
            student_old = rfile.readlines()
    else:
        return

    #输入学生id
    student_id = input("请输入要查找的学生ID：")
    with open("students.txt",'w') as wfile:
        for student in student_old:
            #将从文件中读取的字符串转换成字典
            d = dict(eval(student))
            #判断查找的学生id是否存在，存在则允许修改
            if d['id'] == student_id:
                print("查找到这名学生，可以修改他的信息！！")
                while True:
                    try:
                        d['name'] = input("请输入姓名：")
                        d['english'] = int(input("请输入英语成绩："))
                        d['python'] = int(input("请输入python成绩："))
                        d['c'] = int(input("请输c语言成绩："))
                    except:
                        print("你输入有误，请重新输入！！")
                    else:
                        break
                #将字典转换成字符串
                student = str(d)
                wfile.write(student+"\n")
            else:
                wfile.write(student)
        mask = input("是否继续修改其他学生信息？（y/n）:")
        if mask == 'y':
            modify()

#排序
def sort():
    show()
    if os.path.exists("students.txt"):
        with open("students.txt",'r') as rfile:
            #读取文件中的全部数据信息
            student_old = rfile.readlines()
            #定义一个新列表
            student_new = []
            for student in student_old:
                d = dict(eval(student))
                student_new.append(d)

            ascOrDesc = input("请选择（0：升序，1：降序）")
            if ascOrDesc == '1':
                ascOrDescBool = True
            elif ascOrDesc == '0':
                ascOrDescBool = False
            else:
                print("您输入有误，请重新输入")
                sort()

            mode = input("请选择排序方式（1：按英语成绩排序，2：按python成绩排序，3：按c语言排序，0：按总成绩排序）")
            if mode == '1':
                student_new.sort(key=lambda x:x['english'],reverse=ascOrDescBool)
            elif mode == '2':
                student_new.sort(key=lambda x:x['python'],reverse=ascOrDescBool)
            elif mode == '3':
                student_new.sort(key=lambda x:x['c'],reverse=ascOrDescBool)
            elif mode == '0':
                student_new.sort(key=lambda x:int(x['english']) + int(x['python']) + int(x['c']),reverse=ascOrDescBool)
            else:
                print("您的输入有误，请重新输入")
                sort()

            #显示排序结果
            show_students(student_new)

    else:
        return

#统计学生人数
def total():
    if os.path.exists("students.txt"):
        #读取文件数据信息
        with open("students.txt",'r') as rfile:
            student_old = rfile.readlines()
            if student_old:
                print("一共有%d名学生：" % len(student_old))
            else:
                print("还没有录入学生信息")
    else:
        print("暂未保存数据信息")


#显示所有学生信息
def show():
    student_new = []
    if os.path.exists("students.txt"):
        with open("students.txt",'r') as rfile:
            #读取文件所有内容
            student_old = rfile.readlines()
            for list in student_old:
                #将找到的信息保存到新列表中
                student_new.append(eval(list))
        show_students(student_new)
    else:
        print("暂时未保存学生数据信息...")

#显示所有学生信息
def show_students(studentList):
    if not studentList:
        print("o@o 无数据信息 o@o")
        return
    #格式化显示内容标题，数字代表所占宽度
    format_title = "{:^6}\t{:^12}\t{:^8}\t{:^10}\t{:^10}\t{:^10}"
    #指定格式显示标题
    print(format_title.format("ID","姓名","英语成绩","python成绩","c语言成绩","总成绩"))
    #定义内容显示格式
    format_data = "{:^6}\t{:^12}\t{:^12}\t{:^12}\t{:^12}\t{:^12}"
    for data in studentList:
        #通过循环将列表的内容全部显示出来
        print(format_data.format(data.get("id"),str(data.get("name")),
                                 str(data.get("english")),str(data.get("python")),
                                 str(data.get("c")),
                                 str(int(data.get("english")) + int(data.get("python")) + int(data.get("c")))))


#保存数据到文件
def save(student):
    #try except 获取异常
    try:
        student_txt = open("students.txt","a")  #以追加的模式打开文件
    except:
        student_txt = open("students.txt","w")    #文件不存在，创建文件并打开
    #循环写入内容到文件
    for info in student:
        student_txt.write(str(info) + "\n")
    #关闭文件
    student_txt.close()


#系统主函数
def main():
    ctrl = True
    while(ctrl):
        menu()
        option = input("请选择：")
        option_str = re.sub("\D","",option)
        if option_str in ['0','1','2','3','4','5','6','7']:
            option_int = int(option_str)
            if option_int == 0:
                print('''您已退出学生信息管理系统''')
                ctrl = False
            elif option_int == 1:
                insert()
            elif option_int == 2:
                search()
            elif option_int == 3:
                delete()
            elif option_int == 4:
                modify()
            elif option_int == 5:
                sort()
            elif option_int == 6:
                total()
            elif option_int == 7:
                show()

if __name__ == '__main__':
    main()